<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 skin-theme-clientpref-day vector-sticky-header-enabled" lang="de" dir="ltr"><head>
<meta charset="UTF-8">
<title>Software-Interrupt</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./_res_/favicon.png">
<link rel="canonical" href="https://de.wikipedia.org/wiki/Software-Interrupt"> <link href="./_mw_/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link href="./_mw_/ext.gadget.citeRef.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.defaultPlainlinks.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonHide.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonLayout.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonStyle.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiDarkmode.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiResponsive.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.specialSearch.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="./_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="./_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="./_res_/footer.css">
<link rel="stylesheet" type="text/css" href="./_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Software-Interrupt rootpage-Software-Interrupt skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">Software-Interrupt</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="de" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="de" dir="ltr">
<p>Ein <b>Software-Interrupt</b> ist ein expliziter Aufruf einer Unterfunktion (meist einer Betriebssystem-Funktion).<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> Er hat nichts mit einem <a href="Interrupt" title="Interrupt">Interrupt</a> (asynchrone Unterbrechung) zu tun, obwohl häufig der gleiche Sprungverteiler (Interrupt-Tabelle) benutzt wird.
Solche Funktionsaufrufe werden von Programmen mit Hilfe von speziellen architekturabhängigen Befehlen aufgerufen. Dazu muss die Nummer für die benötigte Unterfunktion bekannt sein. Diese Nummer wird als Index in einer Sprungtabelle (meist Interrupt-Vektor-Tabelle) verwendet, die die Startadresse des Unterprogrammes enthält.
</p>
<div class="mw-heading mw-heading2"><h2 id="Mnemonics">Mnemonics</h2></div>
<p>Übliche <a href="Assemblersprache#Mnemonic" title="Assemblersprache">Mnemonics</a> sind:
</p>
<ul><li>BKPT (<i>Breakpoint</i> bei <a href="Motorola_68000" title="Motorola 68000">Motorola 68000</a>)<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup></li>
<li>INT xxh (<i>Interrupt</i> bei <a href="Intel_8086" title="Intel 8086">Intel 8086</a>)</li>
<li>RST p (<i>Restart at p</i> bei <a href="Zilog_Z80" title="Zilog Z80">Zilog Z80</a>)<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup></li>
<li>SC xxh (<i>System Call</i> bei <a href="Zilog_Z8000" title="Zilog Z8000">Zilog Z8000</a>)</li>
<li>TRAP xh (<i>Trap</i> bei <a href="Motorola_68000" title="Motorola 68000">Motorola 68000</a>)<sup id="cite_ref-4" class="reference"><a href="#cite_note-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup></li>
<li>CALL 0005h (<a href="CP/M" title="CP/M">CP/M-80</a>, der <a href="Intel_8080" title="Intel 8080">Intel 8080</a> hatte keinen speziellen Befehl dafür)</li>
<li>ecall (<i>Environment Call</i> bei <a href="RISC-V" title="RISC-V">RISC-V</a>)<sup id="cite_ref-5" class="reference"><a href="#cite_note-5"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup></li>
<li>svc (<i>Supervisor Call</i> bei <a href="ARM-Architektur" title="ARM-Architektur">ARM</a>)<sup id="cite_ref-6" class="reference"><a href="#cite_note-6"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Hintergründe"><span id="Hintergr.C3.BCnde"></span>Hintergründe</h2></div>
<p>Ursprünglich nur als bequemer und portabler Sprungverteiler (<a href="MS-DOS" title="MS-DOS">MS-DOS</a>) verwendet – man vermied damit versionsabhängige Einsprünge direkt in den Betriebssystem-Code (z. B. <code>JSR $EDB9</code>) – haben diese Funktionsaufrufe bei modernen Betriebssystemen weitere Funktionen bekommen. Mit diesen Befehlen sind Context- und Task-Wechsel möglich, die sich mit klassischen Befehlen (absichtlich) nicht realisieren lassen. So lässt sich der <code>INT 21h</code> unter MS-DOS auch durch klassische Befehle (ca. 20 Stück) nachbilden, allerdings nicht mehr der <code>INT 80h</code>, der zum Aufruf von Betriebssystemfunktionen in <a href="Unix" title="Unix">Unix</a>-Binaries verwendet wird.
</p><p>Diese Technik ermöglicht erst geschützte Betriebssysteme, da der Wechsel in den Kontext des Betriebssystems nur an genau definierten Stellen erfolgen kann.
</p>
<div class="mw-heading mw-heading2"><h2 id="Beispiel_für_Aufruf_(Unix,_Intel_i386)"><span id="Beispiel_f.C3.BCr_Aufruf_.28Unix.2C_Intel_i386.29"></span>Beispiel für Aufruf (Unix, Intel i386)</h2></div>
<p>Es soll die POSIX-Funktion read (Lesen von Daten von einem Filehandle in den Speicher) implementiert werden:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span></span><span class="w"> </span><span class="n">read</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">FileHandle</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="o">*</span><span class="w"> </span><span class="n">Buffer</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">BufferLength</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">;</span>
</pre></div>
<p>Die (Minimal-)Implementierung (in der libc) sieht dann so aus:
</p>
<div style="border: dashed 1px #2F6FAB; padding: 1em" class="mw-highlight mw-highlight-lang-asm mw-content-ltr" dir="ltr"><pre><span></span><span class="c1">; Intel-Syntax: Instruktion Ziel Quelle</span>
<span class="w"> </span><span class="nf">read</span><span class="w"> </span><span class="no">proc</span>
<span class="w"> </span><span class="nf">push</span><span class="w"> </span><span class="no">ebx</span><span class="w"> </span><span class="c1">; Sichern des Inhalts des Registers ebx auf den Stack</span>
<span class="w"> </span><span class="nf">push</span><span class="w"> </span><span class="no">ecx</span><span class="w"> </span><span class="c1">; Sichern des Inhalts des Registers ecx auf den Stack</span>
<span class="w"> </span><span class="nf">push</span><span class="w"> </span><span class="no">edx</span><span class="w"> </span><span class="c1">; Sichern des Inhalts des Registers edx auf den Stack</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">ebx</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="no">esp</span><span class="err">+</span><span class="mi">16</span><span class="p">]</span><span class="w"> </span><span class="c1">; FileHandle</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">ecx</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="no">esp</span><span class="err">+</span><span class="mi">20</span><span class="p">]</span><span class="w"> </span><span class="c1">; Buffer</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">edx</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="no">esp</span><span class="err">+</span><span class="mi">24</span><span class="p">]</span><span class="w"> </span><span class="c1">; BufferLength</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">eax</span><span class="p">,</span><span class="w"> </span><span class="mi">0003</span><span class="no">h</span><span class="w"> </span><span class="c1">; Funktionnummer für read</span>
<span class="w"> </span><span class="nf">int</span><span class="w"> </span><span class="mi">80</span><span class="no">h</span><span class="w"> </span><span class="c1">; Interruptaufruf</span>
<span class="w"> </span><span class="nf">pop</span><span class="w"> </span><span class="no">edx</span><span class="w"> </span><span class="c1">; Zuvor gesicherte Inhalte werden in umgekehrter Reihenfolge vom Stack</span>
<span class="w"> </span><span class="c1">; zurück in die entsprechenden Register kopiert</span>
<span class="w"> </span><span class="nf">pop</span><span class="w"> </span><span class="no">ecx</span>
<span class="w"> </span><span class="nf">pop</span><span class="w"> </span><span class="no">ebx</span>
<span class="w"> </span><span class="nf">cmp</span><span class="w"> </span><span class="no">eax</span><span class="p">,</span><span class="w"> </span><span class="mi">-124</span><span class="w"> </span><span class="c1">; Werte von 0...0FFFFFF84h sind Rückgabewerte, -123...-1 sind (negierte) Fehlernummern</span>
<span class="w"> </span><span class="nf">jbe</span><span class="w"> </span><span class="no">.noError</span>
<span class="w"> </span><span class="nf">neg</span><span class="w"> </span><span class="no">eax</span><span class="w"> </span><span class="c1">; Aus Rückgabewerten -1...-123 werden die Fehlernummern 1...123</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">__errno</span><span class="p">,</span><span class="w"> </span><span class="no">eax</span><span class="w"> </span><span class="c1">; Fehler in errno abspeichern</span>
<span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">eax</span><span class="p">,</span><span class="w"> </span><span class="mi">-1</span>
<span class="w"> </span><span class="nl">.noError:</span>
<span class="w"> </span><span class="nf">ret</span>
<span class="w"> </span><span class="nf">end</span><span class="w"> </span><span class="no">proc</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Behandlung_vom_Prozessor_und_Betriebssystem">Behandlung vom Prozessor und Betriebssystem</h2></div>
<p>Der Befehl <code>INT 80h</code> bewirkt folgendes:
</p>
<ul><li>Da der Sprung über ein Call Gate geht, findet ein Wechsel des Prioritätslevel von 3 (User) auf 0 (<a href="Kernel_(Betriebssystem)" title="Kernel (Betriebssystem)">Kernel</a>) statt,</li>
<li>dann wird durch den Prozessor vom Userspace-Stack auf den Kernelspace-Stack umgeschaltet,</li>
<li>dann das Flagregister gerettet und</li>
<li>schließlich erfolgt ein Sprung zu einer vom Betriebssystem hinterlegten Adresse.</li></ul>
<p>Die erste Aktion im Kernel ist das Abspeichern und Testen der Argumente:
</p>
<ul><li>Darf der Prozess den Speicherbereich zwischen Buffer und Buffer+BufferLength-1 beschreiben?
<ul><li>wenn nein ⇒ EFAULT</li></ul></li>
<li>Ist der FileHandle für diesen Prozess gültig?
<ul><li>wenn nein ⇒ EBADF</li></ul></li>
<li>Ist der Speicherbereich zwischen Buffer und Buffer+BufferLength-1 im Hauptspeicher?</li>
<li>…</li></ul>
<p>Ein ungenügender Test der Argumente war Anfang bis Mitte der 1990er Jahre noch üblich. Das Aufrufen von Systemfunktionen mit rein zufälligen Werten reichte aus, um Betriebssysteme zu „<a href="Absturz_(Computer)" title="Absturz (Computer)">crashen</a>“, das Testprogramm <i>crashme</i> konnte das eindrucksvoll zeigen. Heutzutage ist jedes Betriebssystem um Größenordnungen resistenter gegen solche Angriffe. Mit zufälligen Werten sind keine Angriffe mehr möglich, dafür sind ausgefeilte Szenarien notwendig.
</p><p>Am Ende hat der Kernel den Funktionsaufruf abgearbeitet und gibt mittels <code>IRET</code> die Kontrolle wieder an das Programm zurück. Der Rücksprung erfolgt wieder über ein Call Gate.
</p>
<ul><li>Rücksprungadresse vom Stack holen</li>
<li>Flagregister rekonstruieren</li>
<li>Auf Userspace-Stack zurückschalten</li>
<li>Prioritätslevel wieder auf 3 setzen</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Siehe_auch">Siehe auch</h2></div>
<ul><li><a href="Systemaufruf" title="Systemaufruf">Systemaufruf</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Einzelbelege">Einzelbelege</h2></div>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Jörg Wiegelmann: <cite style="font-style:italic">Softwareentwicklung in C für Mikroprozessoren und Mikrocontroller: C-Programmierung für Embedded-Systeme</cite>. 7. Auflage. VDE Verlag GmbH, Berlin/Offenbach 2017, ISBN 978-3-8007-4328-5, <span style="white-space:nowrap">S.<span style="display:inline-block;width:.2em"> </span>82–83</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rfr_id=info:sid/de.wikipedia.org:Software-Interrupt&rft.au=J%C3%B6rg+Wiegelmann&rft.btitle=Softwareentwicklung+in+C+f%C3%BCr+Mikroprozessoren+und+Mikrocontroller%3A+C-Programmierung+f%C3%BCr+Embedded-Systeme&rft.date=2017&rft.edition=7&rft.genre=book&rft.isbn=9783800743285&rft.pages=82-83&rft.place=Berlin%2FOffenbach&rft.pub=VDE+Verlag+GmbH" style="display:none"> </span></span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text"><i>MOTOROLA M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL</i>. Motorola Inc. 1992, Seite 4-53, <style data-mw-deduplicate="TemplateStyles:r261891140">
/* start https://de.wikipedia.org/ */
.mw-parser-output .webarchiv-memento a{color:inherit}
/* end https://de.wikipedia.org/ */
</style><a rel="nofollow" class="external text" href="https://web.archive.org/web/20230327005627/https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf">Archivierte Kopie</a> (<span class="webarchiv-memento"><a href="Webarchivierung#Begrifflichkeiten" title="Webarchivierung">Memento</a></span> vom 27. März 2023 im <i><a href="Internet_Archive" title="Internet Archive">Internet Archive</a></i>)</span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><a href="#cite_ref-3">↑</a></span> <span class="reference-text">Rodnay Zaks: <i>PROGRAMMING THE Z80</i>. Sybex Inc. 1979, 1981, ISBN 0-89588-094-6, Seiten 182 und 417. <a rel="nofollow" class="external free" href="http://www.z80.info/zip/programming_the_z80_3rd_edition.pdf">http://www.z80.info/zip/programming_the_z80_3rd_edition.pdf</a></span>
</li>
<li id="cite_note-4"><span class="mw-cite-backlink"><a href="#cite_ref-4">↑</a></span> <span class="reference-text"><i>MOTOROLA M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL</i>. Motorola Inc. 1992, Seite 4-188, <a rel="nofollow" class="external text" href="https://web.archive.org/web/20230327005627/https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf">Archivierte Kopie</a> (<span class="webarchiv-memento"><a href="Webarchivierung#Begrifflichkeiten" title="Webarchivierung">Memento</a></span> vom 27. März 2023 im <i><a href="Internet_Archive" title="Internet Archive">Internet Archive</a></i>)</span>
</li>
<li id="cite_note-5"><span class="mw-cite-backlink"><a href="#cite_ref-5">↑</a></span> <span class="reference-text"><span class="cite">Andrew Waterman, Krste Asanović, RISC-V Foundation: <a rel="nofollow" class="external text" href="https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf"><i>The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version 20191213.</i></a> (pdf) 13. Dezember 2019, <span style="white-space:nowrap;">S. 27</span>,<span class="Abrufdatum"> abgerufen am 18. Juli 2023</span> (englisch).</span><span style="display: none;" class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rfr_id=info%3Asid%2Fde.wikipedia.org%3ASoftware-Interrupt&rft.title=The+RISC-V+Instruction+Set+Manual%2C+Volume+I%3A+User-Level+ISA%2C+Document+Version+20191213&rft.description=The+RISC-V+Instruction+Set+Manual%2C+Volume+I%3A+User-Level+ISA%2C+Document+Version+20191213&rft.identifier=https%3A%2F%2Fgithub.com%2Friscv%2Friscv-isa-manual%2Freleases%2Fdownload%2FRatified-IMAFDQC%2Friscv-spec-20191213.pdf&rft.creator=Andrew+Waterman%2C+Krste+Asanovi%C4%87%2C+RISC-V+Foundation&rft.date=2019-12-13&rft.language=en"> </span></span>
</li>
<li id="cite_note-6"><span class="mw-cite-backlink"><a href="#cite_ref-6">↑</a></span> <span class="reference-text"><span class="cite"><a rel="nofollow" class="external text" href="https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/SVC--previously-SWI-?lang=en"><i>ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition: SVC (previously SWI).</i></a> In: <i>Documentation – Arm Developer.</i> Arm Limited, 2022,<span class="Abrufdatum"> abgerufen am 15. Dezember 2023</span> (englisch).</span><span style="display: none;" class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rfr_id=info%3Asid%2Fde.wikipedia.org%3ASoftware-Interrupt&rft.title=ARM+Architecture+Reference+Manual+ARMv7-A+and+ARMv7-R+edition%3A+SVC+%28previously+SWI%29&rft.description=ARM+Architecture+Reference+Manual+ARMv7-A+and+ARMv7-R+edition%3A+SVC+%28previously+SWI%29&rft.identifier=https%3A%2F%2Fdeveloper.arm.com%2Fdocumentation%2Fddi0406%2Fc%2FApplication-Level-Architecture%2FInstruction-Details%2FAlphabetical-list-of-instructions%2FSVC--previously-SWI-%3Flang%3Den&rft.publisher=Arm+Limited&rft.date=2022&rft.language=en"> </span></span>
</li>
</ol></div><!--htdig_noindex--><div><div class="zim-footer">
Dieser Artikel wurde von <a class="external text" title="Zuletzt bearbeitet am 2025-09-24" href="https://de.wikipedia.org/wiki/?title=Software-Interrupt&oldid=260018678">Wikipedia</a> herausgegeben. Der Text ist unter <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.de">Creative Commons Attribution-Share Alike 4.0</a> verfügbar, sofern nicht anders angegeben. Für die Mediendateien können zusätzliche Bedingungen gelten.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="./_webp_/webpHandler.js"></script>
</body></html>